// 标准库加载器 - 处理标准库模块的加载和集成
use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};

/// 标准库模块信息
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct StdlibModule {
    pub name: String,
    pub path: PathBuf,
    pub version: String,
    pub description: String,
    pub exports: Vec<String>,
}

/// 标准库加载器
pub struct StdlibLoader {
    /// 标准库根目录
    #[allow(dead_code)]
    lib_path: PathBuf,
    /// 已加载的模块缓存
    loaded_modules: HashMap<String, StdlibModule>,
    /// 模块搜索路径
    search_paths: Vec<PathBuf>,
}

impl StdlibLoader {
    /// 创建新的标准库加载器
    pub fn new(lib_path: PathBuf) -> Self {
        let mut search_paths = vec![lib_path.clone()];

        // 添加常见的模块搜索路径
        if let Ok(current_dir) = std::env::current_dir() {
            search_paths.push(current_dir.join("lib"));
            search_paths.push(current_dir.join("examples"));
        }

        StdlibLoader {
            lib_path,
            loaded_modules: HashMap::new(),
            search_paths,
        }
    }

    /// 获取默认的标准库路径
    pub fn default_lib_path() -> PathBuf {
        // 尝试从环境变量获取
        if let Ok(lib_path) = std::env::var("MOYAN_LIB_PATH") {
            return PathBuf::from(lib_path);
        }

        // 尝试从可执行文件位置推断
        if let Ok(exe_path) = std::env::current_exe() {
            if let Some(exe_dir) = exe_path.parent() {
                let lib_path = exe_dir.join("lib");
                if lib_path.exists() {
                    return lib_path;
                }
            }
        }

        // 默认使用当前工作目录的 lib 子目录
        PathBuf::from("lib")
    }

    /// 扫描标准库目录，发现所有可用的模块
    #[allow(dead_code)]
    pub fn scan_modules(&mut self) -> Result<Vec<StdlibModule>, String> {
        let mut modules = Vec::new();

        for search_path in &self.search_paths.clone() {
            if !search_path.exists() {
                continue;
            }

            self.scan_directory(&search_path, &mut modules)?;
        }

        // 更新已加载模块缓存
        #[allow(dead_code)]
        for module in &modules {
            self.loaded_modules
                .insert(module.name.clone(), module.clone());
        }

        Ok(modules)
    }

    /// 递归扫描目录
    fn scan_directory(&self, dir: &Path, modules: &mut Vec<StdlibModule>) -> Result<(), String> {
        let entries =
            fs::read_dir(dir).map_err(|e| format!("无法读取目录 {}: {}", dir.display(), e))?;

        for entry in entries {
            let entry = entry.map_err(|e| format!("读取目录项失败: {}", e))?;
            let path = entry.path();

            if path.is_file() {
                if let Some(ext) = path.extension() {
                    if ext == "moyan" {
                        if let Ok(module) = self.parse_module_info(&path) {
                            modules.push(module);
                        }
                    }
                }
            } else if path.is_dir() {
                // 递归扫描子目录
                let _ = self.scan_directory(&path, modules);
            }
        }

        Ok(())
    }

    /// 解析模块文件信息
    fn parse_module_info(&self, path: &Path) -> Result<StdlibModule, String> {
        let content = fs::read_to_string(path)
            .map_err(|e| format!("无法读取模块文件 {}: {}", path.display(), e))?;

        let mut name = String::new();
        let mut version = "1.0.0".to_string();
        let mut description = String::new();
        let mut exports = Vec::new();

        // 解析文件内容，提取模块信息
        for line in content.lines() {
            let line = line.trim();

            // 提取版本信息
            if line.starts_with("# 版本 ") {
                version = line.replace("# 版本 ", "").trim().to_string();
            }

            // 提取描述信息
            if line.starts_with("# 描述 ") {
                description = line.replace("# 描述 ", "").trim().to_string();
            }

            // 提取导出信息（简化处理）
            if line.starts_with("导出 ") || line.starts_with("export ") {
                let export_line = line.replace("导出 ", "").replace("export ", "");
                for export_item in export_line.split(',') {
                    let export_item = export_item.trim();
                    if !export_item.is_empty() && !exports.contains(&export_item.to_string()) {
                        exports.push(export_item.to_string());
                    }
                }
            }
        }

        // 提取模块名称（从文件名或描述）
        if name.is_empty() {
            if let Some(file_stem) = path.file_stem() {
                let file_name = file_stem.to_string_lossy().to_string();
                // 如果是临时文件，使用文件内容中的描述作为模块名
                if file_name.starts_with(".tmp") {
                    // 如果已经有描述信息，使用描述作为模块名
                    if !description.is_empty() {
                        name = description.clone();
                    } else {
                        name = "未知模块".to_string();
                    }
                } else {
                    name = file_name;
                }
            }
        }

        // 如果没有找到描述，使用默认值
        if description.is_empty() {
            description = format!("{} 模块", name);
        }

        Ok(StdlibModule {
            name,
            path: path.to_path_buf(),
            version,
            description,
            exports,
        })
    }

    /// 获取指定名称的模块
    pub fn get_module(&self, name: &str) -> Option<&StdlibModule> {
        self.loaded_modules.get(name)
    }

    /// 检查模块是否存在
    #[allow(dead_code)]
    pub fn has_module(&self, name: &str) -> bool {
        self.loaded_modules.contains_key(name)
    }

    /// 获取所有可用模块
    #[allow(dead_code)]
    pub fn get_all_modules(&self) -> Vec<&StdlibModule> {
        self.loaded_modules.values().collect()
    }

    /// 获取模块的完整路径
    pub fn resolve_module_path(&self, name: &str) -> Option<PathBuf> {
        // 首先检查是否已经是完整路径
        let test_path = PathBuf::from(name);
        if test_path.exists() {
            return Some(test_path);
        }

        // 检查是否带有.moyan扩展名
        if !name.ends_with(".moyan") {
            let with_ext = format!("{}.moyan", name);
            let test_path = PathBuf::from(&with_ext);
            if test_path.exists() {
                return Some(test_path);
            }
        }

        // 在搜索路径中查找
        for search_path in &self.search_paths {
            let mut test_path = search_path.join(name);
            if test_path.exists() {
                return Some(test_path);
            }

            // 尝试添加.moyan扩展名
            if !name.ends_with(".moyan") {
                test_path.set_extension("moyan");
                if test_path.exists() {
                    return Some(test_path);
                }
            }
        }

        None
    }

    /// 验证模块的兼容性
    #[allow(dead_code)]
    pub fn validate_module_compatibility(
        &self,
        module: &StdlibModule,
        required_version: &str,
    ) -> Result<bool, String> {
        // 简单的版本兼容性检查
        // 在实际实现中，可以使用 semver 库进行更复杂的版本比较
        let current_version = &module.version;

        // 这里实现基本的版本号解析和比较
        let current_parts: Vec<&str> = current_version.split('.').collect();
        let required_parts: Vec<&str> = required_version.split('.').collect();

        if current_parts.len() != 3 || required_parts.len() != 3 {
            return Err("版本号格式错误，应为 major.minor.patch".to_string());
        }

        // 比较主版本号（必须相同）
        if current_parts[0] != required_parts[0] {
            return Ok(false);
        }

        // 比较次版本号（当前版本应大于等于要求版本）
        let current_minor = current_parts[1]
            .parse::<u32>()
            .map_err(|_| "次版本号解析失败")?;
        let required_minor = required_parts[1]
            .parse::<u32>()
            .map_err(|_| "次版本号解析失败")?;

        if current_minor < required_minor {
            return Ok(false);
        }

        // 补丁版本号可以不同
        Ok(true)
    }

    /// 获取模块的依赖关系
    #[allow(dead_code)]
    pub fn get_module_dependencies(&self, module_name: &str) -> Result<Vec<String>, String> {
        let module = self
            .get_module(module_name)
            .ok_or_else(|| format!("模块 {} 不存在", module_name))?;

        let content =
            fs::read_to_string(&module.path).map_err(|e| format!("无法读取模块文件: {}", e))?;

        let mut dependencies = Vec::new();

        // 简单的依赖关系解析
        for line in content.lines() {
            let line = line.trim();

            // 查找导入语句
            if line.starts_with("引 ") || line.starts_with("导入 ") || line.starts_with("import ")
            {
                // 提取导入的模块名
                let import_line = line
                    .replace("引 ", "")
                    .replace("导入 ", "")
                    .replace("import ", "");

                // 提取模块名（简化处理）
                if let Some(quote_pos) = import_line.find('"') {
                    if let Some(end_quote) = import_line[quote_pos + 1..].find('"') {
                        let dep_module = &import_line[quote_pos + 1..quote_pos + 1 + end_quote];
                        if !dep_module.is_empty() && !dependencies.contains(&dep_module.to_string())
                        {
                            dependencies.push(dep_module.to_string());
                        }
                    }
                }
            }
        }

        Ok(dependencies)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_stdlib_loader_creation() {
        let lib_path = PathBuf::from("lib");
        let loader = StdlibLoader::new(lib_path);
        assert!(!loader.search_paths.is_empty());
    }

    #[test]
    fn test_module_info_parsing() {
        use std::io::Write;
        use tempfile::NamedTempFile;

        // 创建临时测试文件
        let mut temp_file = NamedTempFile::new().unwrap();
        writeln!(temp_file, "# 版本 1.2.3").unwrap();
        writeln!(temp_file, "# 描述 测试模块").unwrap();
        writeln!(temp_file, "导出 函数1, 函数2").unwrap();
        writeln!(temp_file, "").unwrap();
        writeln!(temp_file, "曰 测试函数").unwrap();
        writeln!(temp_file, "    书 \"测试\"").unwrap();
        writeln!(temp_file, "毕").unwrap();

        let loader = StdlibLoader::new(PathBuf::from("."));
        let module = loader.parse_module_info(temp_file.path()).unwrap();

        // 临时文件应该使用描述作为模块名
        assert_eq!(module.name, "测试模块");
        assert_eq!(module.version, "1.2.3");
        assert_eq!(module.description, "测试模块");
        assert!(module.exports.contains(&"函数1".to_string()));
        assert!(module.exports.contains(&"函数2".to_string()));
    }

    #[test]
    fn test_version_compatibility() {
        let loader = StdlibLoader::new(PathBuf::from("."));

        let module = StdlibModule {
            name: "test".to_string(),
            path: PathBuf::from("test.moyan"),
            version: "2.3.4".to_string(),
            description: "test".to_string(),
            exports: vec![],
        };

        // 兼容：主版本相同，次版本更高
        assert!(
            loader
                .validate_module_compatibility(&module, "2.1.0")
                .unwrap()
        );

        // 不兼容：主版本不同
        assert!(
            !loader
                .validate_module_compatibility(&module, "1.0.0")
                .unwrap()
        );

        // 不兼容：次版本太低
        assert!(
            !loader
                .validate_module_compatibility(&module, "2.4.0")
                .unwrap()
        );
    }
}
